package net.cohoivang.core;

import java.util.ArrayList;

import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;

import net.cohoivang.news.EnableToTopListener;
import net.cohoivang.news.ExpireListener;
import net.cohoivang.news.INews;
import net.cohoivang.news.News;

public final class TopListNews implements EnableToTopListener, ExpireListener{
	
	private ArrayList<INews> newsList;
	private final LinkedList<INews> masterList = new LinkedList<INews>(); 
	private Object lock = new Object();
	
	private long lastSort;
	
	private final int topSize;
		
	private final TopComparator comparator; 
	public TopListNews(int topSize, TopComparator comparator) {
		this.topSize = topSize;
		this.comparator = comparator;
	}


	public void startListenEnableTop() {
		System.out.println("start listening on top news");
		List<Company> companies = ProfileCompany.getInstance().getAllCompany();
		int count = 0;
		for (Company com : companies) {
			for (News news : com.getAllNews()) {
				news.addEnableToTopListener(this);
				count ++;
			}
		}
		System.out.println("Total :" + count + " news are registry to Toplist");		
	}
	@Override
	public void disableFromTop(INews news) {
		// TODO Auto-generated method stub
		masterList.remove(news);
		newsList.remove(news);
	}
	
	@Override
	public void enableToTop(News news, int replacePos) {
		// TODO Auto-generated method stub
		initializeIfNeed(news, replacePos);
	}
	
	@Override
	public void removeOutOfList() {
		// TODO Auto-generated method stub
		
	}
	
	public ArrayList<INews> getTop() {
		initializeIfNeed(null, -1);
		synchronized (lock) {
			return new ArrayList<INews>(newsList);
		}
	}
	
	private void initializeIfNeed(News news, int replacePos) {				
		if (news != null) {
			masterList.add(news);
		}
				
		Collections.sort(masterList, comparator);		
		int actualSize = Math.min(this.topSize, masterList.size());		
		newsList = new ArrayList<INews>(masterList.subList(0, actualSize));
		
		if (news == null) {
			return;
		}
		
		if (replacePos >= topSize) {
			replacePos = 0;
		}
		
		if (replacePos != -1) {			
			newsList.remove(replacePos);
			masterList.remove(replacePos);
			newsList.add(replacePos, news);
			masterList.add(replacePos, news);
		}		
	}





	
}

abstract class TopComparator implements Comparator<INews> {
	
	private final String name;
	int direction = 1;
	public TopComparator(String name) {
		// TODO Auto-generated constructor stub
		this.name = name;
	}
	
	public String getName() {
		return name;
	}
	
	abstract float getValue(INews news);
	
	public final int compare(INews currentNews, INews candidate) {
		float f = getValue(currentNews) - getValue(candidate);
		if (f > 0) {
			return 1;
		} else if (f == 0) {
			return 0;
		} else {
			return -1;
		}				
	}
}

class DateComparator extends TopComparator {

	
	public DateComparator(String name) {
		super(name);
	}
	
	@Override
	float getValue(INews news) {
		return news.getILastUpdateDate().getTime();
	}

	
}
